package com.lifengdi.graphql.config;

import com.lifengdi.graphql.domain.Author;
import com.lifengdi.graphql.service.AuthorService;
import graphql.analysis.MaxQueryComplexityInstrumentation;
import graphql.analysis.MaxQueryDepthInstrumentation;
import graphql.execution.instrumentation.ChainedInstrumentation;
import graphql.execution.instrumentation.Instrumentation;
import graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation;
import org.dataloader.BatchLoader;
import org.dataloader.DataLoader;
import org.dataloader.DataLoaderRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;

/**
 * @author lifengdi
 * @date 2021/12/8 16:36
 */
@Configuration
public class GraphQLConfig {

    @Resource
    private AuthorService authorService;

    @Bean
    public BatchLoader<BigInteger, Author> authorBatchLoader() {
        return keys -> CompletableFuture.supplyAsync(() -> authorService.listByIds(keys));
    }

    @Bean
    public DataLoader<BigInteger, Author> authorDataLoader(BatchLoader<BigInteger, Author> authorBatchLoader) {
        return new DataLoader<>(authorBatchLoader);
    }

    @Bean
    public Instrumentation instrumentation() {
        DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry();
        dataLoaderRegistry.register("author", authorDataLoader(authorBatchLoader()));
        DataLoaderDispatcherInstrumentation dispatcherInstrumentation = new DataLoaderDispatcherInstrumentation(dataLoaderRegistry);
        return new ChainedInstrumentation(Arrays.asList(
                dispatcherInstrumentation,
                new MaxQueryComplexityInstrumentation(100),
                new MaxQueryDepthInstrumentation(10)
        ));
    }
}
